home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 127 / PC Guia 127.iso / Software / Produtividade / OpenOffice.org 2.0.1 / openofficeorg4.cab / pythonscript.py < prev    next >
Text File  |  2005-12-15  |  27KB  |  743 lines

  1. # XScript implementation for python
  2. import uno
  3. import unohelper
  4. import sys
  5. import imp
  6. import time
  7.  
  8. class LogLevel:
  9.     NONE = 0
  10.     ERROR = 1
  11.     DEBUG = 2
  12.  
  13. # Configuration ----------------------------------------------------
  14. LogLevel.use = LogLevel.NONE                # alternatively ERROR or DEBUG
  15. LOG_STDOUT = True                           # True, writes to stdout (difficult on windows)
  16.                                             # False, writes to user/Scripts/python/log.txt
  17. ENABLE_EDIT_DIALOG=False                    # offers a minimal editor for editing.
  18. #-------------------------------------------------------------------
  19.  
  20. def logLevel2String( level ):
  21.     ret = " NONE"
  22.     if level == LogLevel.ERROR:
  23.         ret = "ERROR"
  24.     elif level >= LogLevel.DEBUG:
  25.         ret = "DEBUG"
  26.     return ret
  27.  
  28. def getLogTarget():
  29.     ret = sys.stdout
  30.     if not LOG_STDOUT:
  31.         pathSubst = uno.getComponentContext().ServiceManager.createInstance(
  32.             "com.sun.star.util.PathSubstitution" )
  33.         userInstallation =  pathSubst.getSubstituteVariableValue( "user" )
  34.         if len( userInstallation ) > 0:
  35.             systemPath = uno.fileUrlToSystemPath( userInstallation + "/Scripts/python/log.txt" )
  36.             ret = file( systemPath , "a" )
  37.     return ret
  38.  
  39. class Logger(LogLevel):
  40.     def __init__(self , target ):
  41.         self.target = target
  42.  
  43.     def isDebugLevel( self ):
  44.         return self.use >= self.DEBUG
  45.     
  46.     def debug( self, msg ):
  47.         if self.isDebugLevel():
  48.             self.log( self.DEBUG, msg )
  49.     
  50.     def isErrorLevel( self ):
  51.         return self.use >= self.ERROR
  52.  
  53.     def error( self, msg ):
  54.         if self.isErrorLevel():
  55.             self.log( self.ERROR, msg )
  56.  
  57.     def log( self, level, msg ):
  58.         self.target.write(
  59.             time.asctime() +
  60.             " [" +
  61.             logLevel2String( level ) +
  62.             "] " +
  63.             msg +
  64.             "\n" )
  65.  
  66. log = Logger( getLogTarget() )
  67.  
  68. log.debug( "pythonscript loading" )
  69.  
  70. #from com.sun.star.lang import typeOfXServiceInfo, typeOfXTypeProvider
  71. from com.sun.star.uno import RuntimeException
  72. from com.sun.star.lang import XServiceInfo
  73. from com.sun.star.io import IOException
  74. from com.sun.star.ucb import CommandAbortedException
  75. from com.sun.star.beans import XPropertySet
  76. from com.sun.star.container import XNameContainer
  77. from com.sun.star.xml.sax import XDocumentHandler, InputSource
  78. from com.sun.star.uno import Exception as UnoException
  79. from com.sun.star.script import XInvocation
  80. from com.sun.star.awt import XActionListener
  81.  
  82. from com.sun.star.script.provider import XScriptProvider, XScript, XScriptContext, ScriptFrameworkErrorException
  83. from com.sun.star.script.browse import XBrowseNode
  84. from com.sun.star.script.browse.BrowseNodeTypes import SCRIPT, CONTAINER, ROOT
  85.  
  86. LANGUAGENAME = "Python"
  87. GLOBAL_SCRIPTCONTEXT_NAME = "XSCRIPTCONTEXT"
  88. CALLABLE_CONTAINER_NAME =  "g_exportedScripts"
  89.  
  90. # pythonloader looks for a static g_ImplementationHelper variable
  91. g_ImplementationHelper = unohelper.ImplementationHelper()
  92. g_implName = "org.openoffice.pyuno.LanguageScriptProviderFor"+LANGUAGENAME
  93.  
  94.  
  95.  
  96. BLOCK_SIZE = 65536
  97. def readTextFromStream( inputStream ):
  98.     # read the file
  99.     code = uno.ByteSequence( "" )
  100.     while True:
  101.         read,out = inputStream.readBytes( None , BLOCK_SIZE )
  102.         code = code + out
  103.         if read < BLOCK_SIZE:
  104.            break
  105.     return code.value
  106.     
  107.     
  108. class ModuleEntry:
  109.     def __init__( self, lastRead, module ):
  110.         self.lastRead = lastRead
  111.         self.module = module
  112.  
  113. def hasChanged( oldDate, newDate ):
  114.     return newDate.Year > oldDate.Year or \
  115.            newDate.Month > oldDate.Month or \
  116.            newDate.Day > oldDate.Day or \
  117.            newDate.Hours > oldDate.Hours or \
  118.            newDate.Minutes > oldDate.Minutes or \
  119.            newDate.Seconds > oldDate.Seconds or \
  120.            newDate.HundredthSeconds > oldDate.HundredthSeconds
  121.  
  122. class ScriptContext(unohelper.Base):
  123.     def __init__( self, ctx, doc ):
  124.         self.ctx = ctx
  125.         self.doc = doc
  126.        
  127.    # XScriptContext
  128.     def getDocument(self):
  129.         return self.getDesktop().getCurrentComponent()
  130.  
  131.     def getDesktop(self):
  132.         return self.ctx.ServiceManager.createInstanceWithContext(
  133.             "com.sun.star.frame.Desktop", self.ctx )
  134.  
  135.     def getComponentContext(self):
  136.         return self.ctx
  137.  
  138. #----------------------------------
  139. # Global Module Administration
  140. # does not fit together with script
  141. # engine lifetime management
  142. #----------------------------------
  143. g_scriptContext = ScriptContext( uno.getComponentContext(), None )
  144. g_modules = {}
  145. def getModuleByUrl( url, sfa ):
  146.     entry =  g_modules.get(url)
  147.     load = True
  148.     lastRead = sfa.getDateTimeModified( url )
  149.     if entry:
  150.         if hasChanged( entry.lastRead, lastRead ):
  151.             log.isDebugLevel() and log.debug("file " + url + " has changed, reloading")
  152.         else:
  153.             load = False
  154.             
  155.     if load:
  156.         log.isDebugLevel() and log.debug( "opening >" + url + "<" )
  157.  
  158.         code = readTextFromStream( sfa.openFileRead( url ) )
  159.             
  160.         # execute the module
  161.         entry = ModuleEntry( lastRead, imp.new_module("ooo_script_framework") )
  162.         entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = g_scriptContext
  163.         entry.module.__file__ = url
  164.         exec code in entry.module.__dict__
  165.         g_modules[ url ] = entry
  166.         log.isDebugLevel() and log.debug( "mapped " + url + " to " + str( entry.module ) )
  167.     return entry.module
  168.  
  169. class ProviderContext:
  170.     def __init__( self, storageType, sfa, uriHelper, scriptContext ):
  171.         self.storageType = storageType
  172.         self.sfa = sfa
  173.         self.uriHelper = uriHelper
  174.         self.scriptContext = scriptContext
  175.         self.modules = {}
  176.         self.rootUrl = None
  177.         self.mapPackageName2Path = None
  178.  
  179.     def getTransientPartFromUrl( self, url ):
  180.         rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1)
  181.         return rest[0:rest.find("/")]
  182.     
  183.     def getPackageNameFromUrl( self, url ):
  184.         rest = url.replace( self.rootUrl , "",1 ).replace( "/","",1)
  185.         start = rest.find("/") +1
  186.         return rest[start:rest.find("/",start)]
  187.         
  188.         
  189.     def removePackageByUrl( self, url ):
  190.         items = self.mapPackageName2Path.items()
  191.         for i in items:
  192.             if url in i[1].pathes:
  193.                 self.mapPackageName2Path.pop(i[0])
  194.                 break
  195.  
  196.     def addPackageByUrl( self, url ):
  197.         packageName = self.getPackageNameFromUrl( url )
  198.         transientPart = self.getTransientPartFromUrl( url )
  199.         log.isDebugLevel() and log.debug( "addPackageByUrl : " + packageName + ", " + transientPart )
  200.         if self.mapPackageName2Path.has_key( packageName ):
  201.             package = self.mapPackageName2Path[ packageName ]
  202.             package.pathes = package.pathes + (url, )
  203.         else:
  204.             package = Package( (url,), transientPart)
  205.             self.mapPackageName2Path[ packageName ] = package
  206.     
  207.     def isUrlInPackage( self, url ):
  208.         values = self.mapPackageName2Path.values()
  209.         for i in values:
  210.             if url in i.pathes:
  211.                return True
  212.         return False
  213.             
  214.     def setPackageAttributes( self, mapPackageName2Path, rootUrl ):
  215.         self.mapPackageName2Path = mapPackageName2Path
  216.         self.rootUrl = rootUrl
  217.         
  218.     def getPersistentUrlFromStorageUrl( self, url ):
  219.         # package name is the second directory
  220.         ret = url
  221.         if self.rootUrl:
  222.             pos = len( self.rootUrl) +1
  223.             ret = url[0:pos]+url[url.find("/",pos)+1:len(url)]
  224.         log.isDebugLevel() and log.debug( "getPersistentUrlFromStorageUrl " + url +  " -> "+ ret)
  225.         return ret
  226.  
  227.     def getStorageUrlFromPersistentUrl( self, url):
  228.         ret = url
  229.         if self.rootUrl:
  230.             pos = len(self.rootUrl)+1
  231.             packageName = url[pos:url.find("/",pos+1)]
  232.             package = self.mapPackageName2Path[ packageName ]
  233.             ret = url[0:pos]+ package.transientPathElement + "/" + url[pos:len(url)]
  234.         log.isDebugLevel() and log.debug( "getStorageUrlFromPersistentUrl " + url + " -> "+ ret)
  235.         return ret
  236.     
  237.     def getModuleByUrl( self, url ):
  238.         entry =  self.modules.get(url)
  239.         load = True
  240.         lastRead = self.sfa.getDateTimeModified( url )
  241.         if entry:
  242.             if hasChanged( entry.lastRead, lastRead ):
  243.                 log.isDebugLevel() and log.debug( "file " + url + " has changed, reloading" )
  244.             else:
  245.                 load = False
  246.                 
  247.         if load:
  248.             log.isDebugLevel() and log.debug( "opening >" + url + "<" )
  249.             
  250.             code = readTextFromStream( self.sfa.openFileRead( url ) )
  251.             
  252.             # execute the module
  253.             entry = ModuleEntry( lastRead, imp.new_module("ooo_script_framework") )
  254.             entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.scriptContext
  255.             exec code in entry.module.__dict__
  256.             entry.module.__file__ = url
  257.             self.modules[ url ] = entry
  258.             log.isDebugLevel() and log.debug( "mapped " + url + " to " + str( entry.module ) )
  259.         return  entry.module
  260.         
  261. #--------------------------------------------------
  262. def isScript( candidate ):
  263.     ret = False
  264.     if isinstance( candidate, type(isScript) ):
  265.         ret = True
  266.     return ret
  267.     
  268. #-------------------------------------------------------
  269. class ScriptBrowseNode( unohelper.Base, XBrowseNode , XPropertySet, XInvocation, XActionListener ):
  270.     def __init__( self, provCtx, uri, fileName, funcName, func ):
  271.         self.fileName = fileName
  272.         self.funcName = funcName
  273.         self.provCtx = provCtx
  274.         self.func = func
  275.         self.uri = uri
  276.         
  277.     def getName( self ):
  278.         return self.funcName
  279.  
  280.     def getChildNodes(self):
  281.         return ()
  282.  
  283.     def hasChildNodes(self):
  284.         return False
  285.     
  286.     def getType( self):
  287.         return SCRIPT
  288.  
  289.     def getPropertyValue( self, name ):
  290.         ret = None
  291.         if name == "URI":
  292.             ret = self.provCtx.uriHelper.getScriptURI(
  293.                 self.provCtx.getPersistentUrlFromStorageUrl( self.uri + "$" + self.funcName ) )
  294.         elif name == "Description":
  295.             ret = getattr( self.func, "__doc__", None )
  296.         elif name == "Editable" and ENABLE_EDIT_DIALOG:
  297.             ret = not self.provCtx.sfa.isReadOnly( self.uri )
  298.         
  299.         log.isDebugLevel() and log.debug( "ScriptBrowseNode.getPropertyValue called for " + name + ", returning " + str(ret) )
  300.         return ret
  301.     def setPropertyValue( self, name, value ):
  302.         log.isDebugLevel() and log.debug( "ScriptBrowseNode.setPropertyValue called " + name + "=" +str(value ) )
  303.     def getPropertySetInfo( self ):
  304.         log.isDebugLevel() and log.debug( "ScriptBrowseNode.getPropertySetInfo called "  )
  305.         return None
  306.                
  307.     def getIntrospection( self ):
  308.         return None
  309.  
  310.     def invoke( self, name, params, outparamindex, outparams ):
  311.         if name == "Editable":
  312.             servicename = "com.sun.star.awt.DialogProvider"
  313.             ctx = self.provCtx.scriptContext.getComponentContext()
  314.             dlgprov = ctx.ServiceManager.createInstanceWithContext(
  315.                 servicename, ctx )
  316.  
  317.             self.editor = dlgprov.createDialog(
  318.                 "vnd.sun.star.script:" +
  319.                 "ScriptBindingLibrary.MacroEditor?location=application")
  320.  
  321.             code = readTextFromStream(self.provCtx.sfa.openFileRead(self.uri))
  322.             self.editor.getControl("EditorTextField").setText(code)
  323.  
  324.             self.editor.getControl("RunButton").setActionCommand("Run")
  325.             self.editor.getControl("RunButton").addActionListener(self)
  326.             self.editor.getControl("SaveButton").setActionCommand("Save")
  327.             self.editor.getControl("SaveButton").addActionListener(self)
  328.  
  329.             self.editor.execute()
  330.  
  331.         return None
  332.  
  333.     def actionPerformed( self, event ):
  334.         try:
  335.             if event.ActionCommand == "Run":
  336.                 code = self.editor.getControl("EditorTextField").getText()
  337.                 mod = imp.new_module("ooo_script_framework")
  338.                 mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = self.provCtx.scriptContext
  339.                 exec code in mod.__dict__
  340.                 values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None )
  341.                 if not values:
  342.                     values = mod.__dict__.values()
  343.                     
  344.                 for i in values:
  345.                     if isScript( i ):
  346.                         i()
  347.                         break
  348.                     
  349.             elif event.ActionCommand == "Save":
  350.                 toWrite = uno.ByteSequence(
  351.                     str(
  352.                     self.editor.getControl("EditorTextField").getText().encode(
  353.                     sys.getdefaultencoding())) )
  354.                 copyUrl = self.uri + ".orig"
  355.                 self.provCtx.sfa.move( self.uri, copyUrl )
  356.                 out = self.provCtx.sfa.openFileWrite( self.uri )
  357.                 out.writeBytes( toWrite )
  358.                 out.close()
  359.                 self.provCtx.sfa.kill( copyUrl )
  360. #                log.isDebugLevel() and log.debug("Save is not implemented yet")
  361. #                text = self.editor.getControl("EditorTextField").getText()
  362. #                log.isDebugLevel() and log.debug("Would save: " + text)
  363.         except Exception,e:
  364.             # TODO: add an error box here !
  365.             log.error( str( e) )
  366.             
  367.  
  368.     def setValue( self, name, value ):
  369.         return None
  370.  
  371.     def getValue( self, name ):
  372.         return None
  373.  
  374.     def hasMethod( self, name ):
  375.         return False
  376.  
  377.     def hasProperty( self, name ):
  378.         return False
  379.  
  380.     
  381. #-------------------------------------------------------
  382. class FileBrowseNode( unohelper.Base, XBrowseNode ):
  383.     def __init__( self, provCtx, uri , name ):
  384.         self.provCtx = provCtx
  385.         self.uri = uri
  386.         self.name = name
  387.         self.module = None
  388.         
  389.     def getName( self ):
  390.         return self.name
  391.  
  392.     def getChildNodes(self):
  393.         ret = ()
  394.         try:
  395.             self.module = self.provCtx.getModuleByUrl( self.uri )
  396.             values = self.module.__dict__.get( CALLABLE_CONTAINER_NAME , None )
  397.             
  398.             # no g_exportedScripts, export every function
  399.             if not isinstance(values, type(())):
  400.                 values = self.module.__dict__.values()
  401.                     
  402.             scriptNodeList = []
  403.             for i in values:
  404.                 if isScript( i ):
  405.                     scriptNodeList.append(
  406.                         ScriptBrowseNode(
  407.                         self.provCtx, self.uri, self.name, i.__name__, i  ))
  408.             ret = tuple( scriptNodeList )
  409.             # must compile  !
  410.             log.isDebugLevel() and log.debug( "returning " +str(len(ret)) + " ScriptChildNodes on " + self.uri )
  411.         except Exception, e:
  412.             log.error( "Error " + str(e) + " while evaluating " + self.uri )
  413.             raise e
  414.                    # ret = ()
  415.         return ret
  416.  
  417.     def hasChildNodes(self):
  418.         try:
  419.             return len(self.getChildNodes()) > 0
  420.         except Exception, e:
  421.             return False
  422.     
  423.     def getType( self):
  424.         return CONTAINER
  425.  
  426.         
  427.  
  428. class DirBrowseNode( unohelper.Base, XBrowseNode ):
  429.     def __init__( self, provCtx, name, rootUrl ):
  430.         self.provCtx = provCtx
  431.         self.name = name
  432.         self.rootUrl = rootUrl
  433.  
  434.     def getName( self ):
  435.         return self.name
  436.  
  437.     def getChildNodes( self ):
  438.         try:
  439.             log.isDebugLevel() and log.debug( "DirBrowseNode.getChildNodes called for " + self.rootUrl )
  440.             contents = self.provCtx.sfa.getFolderContents( self.rootUrl, True )
  441.             browseNodeList = []
  442.             for i in contents:
  443.                 if i.endswith( ".py" ):
  444.                     log.isDebugLevel() and log.debug( "adding filenode " + i )
  445.                     browseNodeList.append(
  446.                         FileBrowseNode( self.provCtx, i, i[i.rfind("/")+1:len(i)-3] ) )
  447.                 elif self.provCtx.sfa.isFolder( i ):
  448.                     log.isDebugLevel() and log.debug( "adding DirBrowseNode " + i )
  449.                     browseNodeList.append( DirBrowseNode( self.provCtx, i[i.rfind("/")+1:len(i)],i))
  450.             return tuple( browseNodeList )
  451.         except Exception, e:
  452.             log.error( "DirBrowseNode error: " + str(e) + " while evaluating " + self.rootUrl)
  453.             return ()
  454.  
  455.     def hasChildNodes( self ):
  456.         return True
  457.  
  458.     def getType( self ):
  459.         return CONTAINER
  460.  
  461.     def getScript( self, uri ):
  462.         log.debug( "DirBrowseNode getScript " + uri + " invoked" )
  463.         raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 )
  464.  
  465.  
  466. class ManifestHandler( XDocumentHandler, unohelper.Base ):
  467.     def __init__( self, rootUrl ):
  468.         self.rootUrl = rootUrl
  469.         
  470.     def startDocument( self ):
  471.         self.urlList = []
  472.         
  473.     def endDocument( self ):
  474.         pass
  475.         
  476.     def startElement( self , name, attlist):
  477.         if name == "manifest:file-entry":
  478.             if attlist.getValueByName( "manifest:media-type" ) == "application/vnd.sun.star.framework-script":
  479.                 self.urlList.append(
  480.                     self.rootUrl + "/" + attlist.getValueByName( "manifest:full-path" ) )
  481.  
  482.     def endElement( self, name ):
  483.         pass
  484.  
  485.     def characters ( self, chars ):
  486.         pass
  487.  
  488.     def ignoreableWhitespace( self, chars ):
  489.         pass
  490.  
  491.     def setDocumentLocator( self, locator ):
  492.         pass
  493.  
  494.  
  495. # extracts META-INF directory from 
  496. def getPathesFromPackage( rootUrl, sfa ):
  497.     ret = ()
  498.     try:
  499.         fileUrl = rootUrl + "/META-INF/manifest.xml" 
  500.         inputStream = sfa.openFileRead( fileUrl )
  501.         parser = uno.getComponentContext().ServiceManager.createInstance( "com.sun.star.xml.sax.Parser" )
  502.         handler = ManifestHandler( rootUrl )
  503.         parser.setDocumentHandler( handler )
  504.         parser.parseStream( InputSource( inputStream , "", fileUrl, fileUrl ) )
  505.         ret = tuple( handler.urlList )
  506.     except UnoException, e:
  507.         log.debug( "getPathesFromPackage " + fileUrl + " Exception: " +str( e) )
  508.         pass
  509.     return ret
  510.     
  511.  
  512. class Package:
  513.     def __init__( self, pathes, transientPathElement ):
  514.         self.pathes = pathes
  515.         self.transientPathElement = transientPathElement
  516.  
  517. def getPackageName2PathMap( sfa, rootUrl ):
  518.     ret = {}
  519.     contents = sfa.getFolderContents( rootUrl, True )
  520.     for i in contents:
  521.         if sfa.isFolder( i ):
  522.             transientPathElement = lastElement( i )
  523.             subcontents = sfa.getFolderContents( i , True )
  524.             for j in subcontents:
  525.                 if sfa.isFolder( j ):
  526.                     # ok, found a package. Now let's have a look, if
  527.                     # it contains scripts
  528.                     pathes = getPathesFromPackage( j, sfa )
  529.                     if len( pathes ) > 0:
  530.                         # map package name to url, we need this later
  531.                         log.isDebugLevel() and log.debug( "adding Package " + transientPathElement + " " + str( pathes ) )
  532.                         ret[ lastElement( j ) ] = Package( pathes, transientPathElement )
  533.     return ret
  534.  
  535. def lastElement( aStr):
  536.     return aStr[ aStr.rfind( "/" )+1:len(aStr)]
  537.  
  538. class PackageBrowseNode( unohelper.Base, XBrowseNode ):
  539.     def __init__( self, provCtx, name, rootUrl ):
  540.         self.provCtx = provCtx
  541.         self.name = name
  542.         self.rootUrl = rootUrl
  543.  
  544.     def getName( self ):
  545.         return self.name
  546.  
  547.     def getChildNodes( self ):
  548.         items = self.provCtx.mapPackageName2Path.items()
  549.         browseNodeList = []
  550.         for i in items:
  551.             if len( i[1].pathes ) == 1:
  552.                 browseNodeList.append(
  553.                     DirBrowseNode( self.provCtx, i[0], i[1].pathes[0] ))
  554.             else:
  555.                 for j in i[1].pathes:
  556.                     browseNodeList.append(
  557.                         DirBrowseNode( self.provCtx, i[0]+"."+lastElement(j), j ) )
  558.         return tuple( browseNodeList )
  559.  
  560.     def hasChildNodes( self ):
  561.         return len( self.mapPackageName2Path ) > 0
  562.  
  563.     def getType( self ):
  564.         return CONTAINER
  565.  
  566.     def getScript( self, uri ):
  567.         log.debug( "DirBrowseNode getScript " + uri + " invoked" )
  568.         raise IllegalArgumentException( "PackageBrowseNode couldn't instantiate script " + uri , self , 0 )
  569.  
  570.  
  571.  
  572.  
  573. class PythonScript( unohelper.Base, XScript ):
  574.     def __init__( self, func, mod ):
  575.         self.func = func
  576.         self.mod = mod
  577.     def invoke(self, args, out, outindex ):
  578.         log.isDebugLevel() and log.debug( "PythonScript.invoke " + str( args ) )
  579. #        try:
  580.         ret = self.func( *args )
  581. #        except Exception,e:
  582. #            raise RuntimeException( "Error during invoking function " + str(self.func.__name__) + " in module " +
  583. #                                    self.mod.__file__ + " (" + str( e ) + ")", self )
  584.         log.isDebugLevel() and log.debug( "PythonScript.invoke ret = " + str( ret ) )
  585.         return ret, (), ()
  586.  
  587. def expandUri(  uri ):
  588.     if uri.startswith( "vnd.sun.star.expand:" ):
  589.         uri = uri.replace( "vnd.sun.star.expand:", "",1)
  590.         uri = uno.getComponentContext().getByName(
  591.                     "/singletons/com.sun.star.util.theMacroExpander" ).expandMacros( uri )
  592.     return uri
  593.     
  594. #--------------------------------------------------------------
  595. class PythonScriptProvider( unohelper.Base, XBrowseNode, XScriptProvider, XNameContainer):
  596.     def __init__( self, ctx, *args ):
  597.         if log.isDebugLevel():
  598.             mystr = ""
  599.             for i in args:
  600.                 if len(mystr) > 0:
  601.                     mystr = mystr +","
  602.                 mystr = mystr + str(i)
  603.             log.debug( "Entering PythonScriptProvider.ctor" + mystr )
  604.  
  605.         storageType = ""
  606.         if isinstance(args[0],unicode ):
  607.             storageType = args[0]
  608.         else:
  609.             storageType = args[0].SCRIPTING_DOC_URI
  610.         isPackage = storageType.endswith( ":uno_packages" )
  611.  
  612.         try:
  613.             urlHelper = ctx.ServiceManager.createInstanceWithArgumentsAndContext(
  614.                 "com.sun.star.script.provider.ScriptURIHelper", (LANGUAGENAME, storageType), ctx)
  615.             
  616.             log.isDebugLevel() and log.debug( "got urlHelper " + str( urlHelper ) )
  617.         
  618.             rootUrl = urlHelper.getRootStorageURI()
  619.             log.isDebugLevel() and log.debug( storageType + " transformed to " + rootUrl )
  620.  
  621.             ucbService = "com.sun.star.ucb.SimpleFileAccess"
  622.             sfa = ctx.ServiceManager.createInstanceWithContext( ucbService, ctx )
  623.             if not sfa:
  624.                 log.debug("PythonScriptProvider couldn't instantiate " +ucbService)
  625.                 raise RuntimeException(
  626.                     "PythonScriptProvider couldn't instantiate " +ucbService, self)
  627.             self.provCtx = ProviderContext(
  628.                 storageType, sfa, urlHelper, ScriptContext( uno.getComponentContext(), None ) )
  629.             if isPackage:
  630.                 mapPackageName2Path = getPackageName2PathMap( sfa, rootUrl )
  631.                 self.provCtx.setPackageAttributes( mapPackageName2Path , rootUrl )
  632.                 self.dirBrowseNode = PackageBrowseNode( self.provCtx, LANGUAGENAME, rootUrl )
  633.             else:
  634.                 self.dirBrowseNode = DirBrowseNode( self.provCtx, LANGUAGENAME, rootUrl )
  635.             
  636.         except Exception, e:
  637.             log.debug( "PythonScriptProvider could not be instantiated because of : " + str( e ) )
  638.             raise e
  639.  
  640.     def getName( self ):
  641.         return self.dirBrowseNode.getName()
  642.  
  643.     def getChildNodes( self ):
  644.         return self.dirBrowseNode.getChildNodes()    
  645.  
  646.     def hasChildNodes( self ):
  647.         return self.dirBrowseNode.hasChildNodes()
  648.  
  649.     def getType( self ):
  650.         return self.dirBrowseNode.getType()
  651.  
  652.     def getScript( self, uri ):
  653.         log.debug( "DirBrowseNode getScript " + uri + " invoked" )
  654.         
  655.         raise IllegalArgumentException( "DirBrowseNode couldn't instantiate script " + uri , self , 0 )
  656.  
  657.     def getScript( self, scriptUri ):
  658.         try:
  659.             log.isDebugLevel() and log.debug( "getScript " + scriptUri + " invoked")
  660.             
  661.             storageUri = self.provCtx.getStorageUrlFromPersistentUrl(
  662.                 self.provCtx.uriHelper.getStorageURI(scriptUri) );
  663.             log.isDebugLevel() and log.debug( "getScript: storageUri = " + storageUri)
  664.             fileUri = storageUri[0:storageUri.find( "$" )]
  665.             funcName = storageUri[storageUri.find( "$" )+1:len(storageUri)]        
  666.             
  667.             mod = self.provCtx.getModuleByUrl( fileUri )
  668.             log.isDebugLevel() and log.debug( " got mod " + str(mod) )
  669.             
  670.             func = mod.__dict__[ funcName ]
  671.  
  672.             log.isDebugLevel() and log.debug( "got func " + str( func ) )
  673.             return PythonScript( func, mod )
  674.         except Exception, e:
  675.             log.error( str( e ) )
  676.             raise ScriptFrameworkErrorException( str(e), self, scriptUri, LANGUAGENAME, 0 )
  677.         
  678.  
  679.     # XServiceInfo
  680.     def getSupportedServices( self ):
  681.         return g_ImplementationHelper.getSupportedServices(g_implName)
  682.  
  683.     def supportsService( self, ServiceName ):
  684.         return g_ImplementationHelper.supportsService( g_implName, ServiceName )
  685.  
  686.     def getImplementationName(self):
  687.         return g_implName
  688.  
  689.     def getByName( self, name ):
  690.         log.debug( "getByName called" + str( name ))
  691.         return None
  692.  
  693.         
  694.     def getElementNames( self ):
  695.         log.debug( "getElementNames called")
  696.         return ()
  697.     
  698.     def hasByName( self, name ):
  699.         try:
  700.             log.debug( "hasByName called " + str( name ))
  701.             uri = expandUri(name)
  702.             ret = self.provCtx.isUrlInPackage( uri )
  703.             log.debug( "hasByName " + uri + " " +str( ret ) )
  704.             return ret
  705.         except Exception, e:
  706.             log.debug( "Error in hasByName:" +  str(e) )
  707.             return False
  708.  
  709.     def removeByName( self, name ):
  710.         log.debug( "removeByName called" + str( name ))
  711.         uri = expandUri( name )
  712.         self.provCtx.removePackageByUrl( uri )
  713.         log.debug( "removeByName called" + str( uri ) + " successful" )
  714.         
  715.     def insertByName( self, name, value ):
  716.         log.debug( "insertByName called " + str( name ) + " " + str( value ))
  717.         uri = expandUri( name )
  718.         self.provCtx.addPackageByUrl( uri )
  719.         log.debug( "insertByName called" + str( uri ) + " successful" )
  720.  
  721.     def replaceByName( self, name, value ):
  722.         log.debug( "replaceByName called " + str( name ) + " " + str( value ))
  723.         removeByName( name )
  724.         insertByName( name )
  725.         log.debug( "replaceByName called" + str( uri ) + " successful" )
  726.  
  727.     def getElementType( self ):
  728.         log.debug( "getElementType called" )
  729.         return uno.getTypeByName( "void" )
  730.     
  731.     def hasElements( self ):
  732.         log.debug( "hasElements got called")
  733.         return False
  734.     
  735. g_ImplementationHelper.addImplementation( \
  736.     PythonScriptProvider,g_implName, \
  737.     ("com.sun.star.script.provider.LanguageScriptProvider",
  738.      "com.sun.star.script.provider.ScriptProviderFor"+ LANGUAGENAME,),)
  739.  
  740.  
  741. log.debug( "pythonscript finished intializing" )
  742.  
  743.